package com.think.grpcserver

import android.annotation.SuppressLint
import com.think.protocol.*
import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder
import io.grpc.stub.StreamObserver
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit


object Server {

    private const val PORT = 5001

    var isStart = false

    lateinit var callResponse: CallResponse

    val greeter by lazy {
        GreeterImpl()
    }
    val mSer by lazy {
        MSerImpl()
    }

    val server by lazy {
        NettyServerBuilder
            .forPort(PORT)
            .addService(greeter)
            .addService(mSer)
            .build()
    }

    fun init(callResponse: CallResponse) {
        this.callResponse = callResponse
    }

    fun start() {
        LogUtil.d("server.isShutdown=${server.isShutdown}")


        if (isStart) {
            callResponse.onBlock("start:已经初始化过")
            return
        }
        server.start()
        LogUtil.d("Server running on port {${PORT}}")
        isStart = true
        callResponse.onBlock("start:初始化=Server running on port {${PORT}}")

//        Thread(Runnable {
//            Runtime.getRuntime().addShutdownHook(Thread { server.shutdown() })
//            server.awaitTermination()
//
//        }).start()
    }

    fun stop() {
        if (!isStart) {
            callResponse.onBlock("stop:未初始化")
            return
        }
        isStart = false
        server.shutdownNow()
        callResponse.onBlock("stop: 关闭 port {${PORT}}")

    }


    class GreeterImpl : GreeterGrpc.GreeterImplBase() {
        override fun sayHello(req: HelloRequest, responseObserver: StreamObserver<HelloReply>) {
            val msg = "Hello " + req.getName()
            callResponse.onBlock("GreeterGrpc_sayHello_Request:${msg}")
            val reply: HelloReply = HelloReply.newBuilder().setMessage(msg).build()
            responseObserver.onNext(reply)
            responseObserver.onCompleted()
        }

    }


    class MSerImpl : MserviceGrpc.MserviceImplBase() {

        @SuppressLint("SimpleDateFormat")
        override fun getSerTime(request: Empty, responseObserver: StreamObserver<StrReply>) {
            callResponse.onBlock("MserviceGrpc_getCurrrTime_Request:null")
            val reply: StrReply = StrReply.newBuilder().setMessage(getCurrTimeStr()).build()
            responseObserver.onNext(reply)
            responseObserver.onCompleted()
        }

        override fun getSerStreamTime(
            request: Empty,
            responseObserver: StreamObserver<StrReply>
        ) {
            callResponse.onBlock("MserviceGrpc_getSerStreamTime_Request:null")

            for (i in 1..10) {
                Thread.sleep(500)
                val reply: StrReply =
                    StrReply.newBuilder().setMessage("服务端处理-i=${i}${getCurrTimeStr()}").build()
                responseObserver.onNext(reply)
            }
            responseObserver.onCompleted()

        }


        override fun uploadFileStream(responseObserver: StreamObserver<FileNameList>): StreamObserver<FileInfo> {
            val fileNameList = mutableListOf<StrReply>()
            callResponse.onBlock("MserviceGrpc_uploadFileStream_Request:is Stream")
            return object : StreamObserver<FileInfo> {
                override fun onNext(value: FileInfo) {
                    LogUtil.d("uploadFileStream--onNext--${value.fileName}")
                    callResponse.onBlock("uploadFileStream-onNext-${value.fileName}")

                    fileNameList.add(StrReply.newBuilder().setMessage("服务端处理--${value.fileName}").build())
                }

                override fun onError(t: Throwable?) {


                }

                override fun onCompleted() {
                    LogUtil.d("uploadFileStream--onCompleted")

                    responseObserver.onNext(
                        FileNameList.newBuilder().addAllStr(fileNameList).build()
                    )
                    responseObserver.onCompleted()
                }

            }
        }

        override fun downloadStream(responseObserver: StreamObserver<FileInfo>): StreamObserver<FilePath> {
            callResponse.onBlock("MserviceGrpc_downloadStream_Request:is Stream")
            return object : StreamObserver<FilePath> {
                override fun onNext(value: FilePath) {

                    val msg = "服务端处理${value.path}"
                    callResponse.onBlock("downloadStream-onNext-${msg}")

                    responseObserver.onNext(
                        FileInfo.newBuilder().setFileName(msg).build()
                    )
                }

                override fun onError(t: Throwable?) {
                    responseObserver.onError(t)

                }

                override fun onCompleted() {
                    LogUtil.d("uploadFileStream--onCompleted")
                    responseObserver.onCompleted()
                }

            }

        }


    }


    private fun getCurrTimeStr(): String {
        val format = SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS")
        val d1 = Date(System.currentTimeMillis())
        val t1: String = format.format(d1)
        return "服务端：${t1}"
    }
}

